/*
 * Copyright (C) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import fs from '@ohos.file.fs';


export class FileReader {
  // 换行符
  static readonly LF: string = '\n'

  // CR符
  static readonly CR: string = '\r'


  // 文件大小
  fileLength: number = 0

  // 读取的长度
  length: number = 0

  // 读写stream
  stream: fs.Stream | null = null

  // 缓存buf
  buf: ArrayBuffer = new ArrayBuffer(1)

  /**
   * 读取文件行
   *
   * @param path 文件路径
   */
  constructor(path: string | FileReader) {
    if (path instanceof FileReader){
      this.stream = path.stream
      this.fileLength = path.fileLength
      return
    }
    this.stream = fs.createStreamSync(path, 'r+');
    let stat = fs.statSync(path)
    this.fileLength = stat.size
  }

  readNumber(): number{
    let numberStr = '';
    const digitSet = new Set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']);

    while (this.length < this.fileLength) {
      // 正确读取一个字节：不传 offset，或 offset: 0
      let bytesRead = this.stream.readSync(this.buf) //, { offset: this.length })
      if (bytesRead === 0) break; // 安全检查

      this.length++; // 已读字节数 +1
      let temp = String.fromCharCode.apply(null, new Uint8Array(this.buf));

      if (digitSet.has(temp)) {
        numberStr += temp; // ← 关键：拼接数字！
      } else {
        break; // 遇到非数字，停止
      }
    }

    if (numberStr === '') {
      return -1; // 或抛异常
    }

    const num = parseInt(numberStr, 10);
    return isNaN(num) ? -1 : num;
  }
  /**
   * 循环读取文件数据
   */
  readLine(): string {
    let line = ''
    while (this.length < this.fileLength) {
      this.stream.readSync(this.buf) //, { offset: this.length })
      this.length++
      let temp = String.fromCharCode.apply(null, new Uint8Array(this.buf));
      // check CRLF
      if (temp == FileReader.CR) {
        // 边界判断 首先拿到下一个字符判断是否是LF 如果是CRLF需要再向后挪一位
        if(this.length < this.fileLength) {
          let nextBuf = new ArrayBuffer(1)
          this.stream.readSync(nextBuf)// , { offset: this.length })
          let nextTemp = String.fromCharCode.apply(null, new Uint8Array(nextBuf))
          // 如果是CRLF 需要给当前length+1 向后挪一位
          if (nextTemp == FileReader.LF) {
            this.length++
          }
        }
        // 如果不是CRLF 只有一个CR结尾length不用变
        return line;
      }
      // 处理 \n (LF)
      if (temp === FileReader.LF) {
        return line; // 不包含 \n
      }
      line += temp;
    }
    return line
  }

  /**
   * 判断文件是否结束
   */
  isEnd() {
    return this.fileLength <= 0 || this.length == this.fileLength
  }

  /**
   * 关闭stream
   */
  close() {
    try{
      this.stream.closeSync()
    }catch (_) {
    }
  }
}